package com.cloud.admin.config;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final AdminServerProperties adminServer;

    public SecurityConfig(AdminServerProperties adminServer) {
        this.adminServer = adminServer;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests((authorizeRequests) -> authorizeRequests
            .antMatchers(this.adminServer.path("/assets/**")).permitAll()
            .antMatchers(this.adminServer.path("/actuator/**")).permitAll()
            .antMatchers(this.adminServer.path("/v1/agent/self")).permitAll()
            .antMatchers(this.adminServer.path("/v1/catalog/services")).permitAll()
            .antMatchers(this.adminServer.path("/v1/health/service/**")).permitAll()
            .antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated()
        );

        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
        http.formLogin((formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler));

        http.logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults())
            .csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringRequestMatchers(
                    new AntPathRequestMatcher(this.adminServer.path("/instances")),
                    new AntPathRequestMatcher(this.adminServer.path("/instances/*")),
                    new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))
                ));
    }
}
